// Copyright 2016 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include <absl/log/log.h>
#include <gtest/gtest.h>
#include <functional>

#include "packager/media/base/text_sample.h"
#include "packager/media/base/text_stream_info.h"
#include "packager/media/formats/mp2t/es_parser_teletext.h"

namespace shaka {
namespace media {
namespace mp2t {

namespace {

const uint8_t DESCRIPTOR[] = {0x56, 0x0a, 0x63, 0x61, 0x74, 0x09,
                              0x00, 0x63, 0x61, 0x74, 0x10, 0x88};

const uint8_t PES_283413[] = {
    0x10, 0x02, 0x2c, 0xe7, 0xe4, 0x92, 0x85, 0x80, 0xfe, 0x6b, 0x97, 0xce,
    0x97, 0x2f, 0xa7, 0xce, 0x40, 0xfe, 0x0b, 0xfb, 0x46, 0x37, 0x97, 0xc7,
    0xc1, 0x04, 0xfe, 0x32, 0x86, 0x04, 0x43, 0xf7, 0x2f, 0x97, 0xe6, 0x86,
    0x61, 0xfe, 0x05, 0x76, 0x26, 0xa7, 0x1f, 0x04, 0x2a, 0x6b, 0xc2, 0x03,
    0x2c, 0xe8, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8, 0x0b, 0xf4,
    0xd9, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c, 0x04, 0x04,
    0x04, 0x8c, 0x8c, 0x8c, 0x04, 0x8c, 0x6d, 0x5d, 0x0d, 0x03, 0x2c, 0xe9,
    0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8, 0x0b, 0xf4, 0xd9, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c, 0x04, 0x04, 0x04, 0x8c,
    0x8c, 0x8c, 0x04, 0x8c, 0x6d, 0x5d, 0x0d, 0x03, 0x2c, 0xea, 0xe4, 0xa8,
    0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8, 0x0b, 0xf4, 0xd9, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c, 0x04, 0x04, 0x04, 0x8c, 0x8c, 0x8c,
    0x04, 0x8c, 0x6d, 0x5d, 0x0d, 0x03, 0x2c, 0xc7, 0xe4, 0xa8, 0x6d, 0xa8,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0xb7, 0xc0, 0x00, 0x03, 0x2c, 0xc8, 0xe4, 0x0b, 0x6d, 0xa8, 0x57, 0x57,
    0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57,
    0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57,
    0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0xa8, 0xec,
    0x82, 0x03, 0x2c, 0xc9, 0xe4, 0xa8, 0xd9, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xb0, 0xd0, 0xd0,
    0x43, 0xf7, 0x76, 0x04, 0x26, 0x97, 0x86, 0x85, 0x51, 0x51, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04};

const uint8_t PES_407876[] = {
    0x10, 0x02, 0x2c, 0xe7, 0xe4, 0x7a, 0x85, 0x80, 0xfe, 0x0b, 0x7f, 0xe6,
    0x75, 0xd5, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x61, 0xfe, 0x0b, 0x7f, 0xe6, 0x75, 0xb5, 0x03,
    0x2c, 0xe8, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8, 0x0b, 0xf4,
    0xd9, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c, 0x04, 0x04,
    0x04, 0x04, 0x8c, 0x6d, 0x5d, 0x0d, 0xcd, 0x5d, 0x4c, 0x03, 0x2c, 0xe9,
    0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8, 0x0b, 0xf4, 0xd9, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c, 0x04, 0x04, 0x04, 0x04,
    0x8c, 0x6d, 0x5d, 0x0d, 0xcd, 0x5d, 0x4c, 0x03, 0x2c, 0xea, 0xe4, 0xa8,
    0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8, 0x0b, 0xf4, 0xd9, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c, 0x04, 0x04, 0x04, 0x04, 0x8c, 0x6d,
    0x5d, 0x0d, 0xcd, 0x5d, 0x4c, 0x03, 0x2c, 0xc7, 0xe4, 0xa8, 0x6d, 0xa8,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0xf9, 0x2d, 0x00, 0x03, 0x2c, 0xc8, 0xe4, 0x0b, 0x6d, 0xa8, 0x57, 0x57,
    0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57,
    0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57,
    0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0xa8, 0x00,
    0x00, 0x02, 0x2c, 0xc9, 0xe4, 0x40, 0xa8, 0xa8, 0xa8, 0x40, 0x0b, 0xa8,
    0xa8, 0xa8, 0x31, 0x2a, 0x6b, 0xcd, 0x2a, 0xa2, 0x1a, 0x2a, 0xc1, 0x2a,
    0x6b, 0xcd, 0xe0, 0x8c, 0x0d, 0x0d, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c,
    0xc1, 0x04, 0x04, 0x04, 0x8c, 0x6d, 0x5d, 0x0d, 0xcd, 0x5d, 0x4c};

const uint8_t PES_8768632[] = {
    0x10, 0x02, 0x2c, 0xe7, 0xe4, 0x92, 0x0b, 0xc8, 0x34, 0x34, 0x34, 0x34,
    0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
    0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
    0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x02,
    0x2c, 0xe8, 0xe4, 0x92, 0xe3, 0x40, 0x73, 0xf7, 0x2f, 0xba, 0xc7, 0x97,
    0xa7, 0xce, 0x04, 0xa7, 0xce, 0x0e, 0xf7, 0x4f, 0x2f, 0x97, 0x6e, 0xa7,
    0xce, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x8c, 0xad, 0x0d, 0x02, 0x2c, 0xe9,
    0xe4, 0x31, 0x31, 0xc8, 0xb9, 0x01, 0xb0, 0x0b, 0x4f, 0xf7, 0xe6, 0x4f,
    0x86, 0xb6, 0x86, 0xc7, 0x97, 0x7a, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x75, 0x75, 0xcd, 0x0d, 0x0d, 0x02, 0x2c, 0xea, 0xe4, 0x31,
    0xd9, 0xe0, 0xb9, 0x01, 0x04, 0x92, 0x76, 0x67, 0xf7, 0x4f, 0xb6, 0x86,
    0xc7, 0x97, 0x7a, 0x04, 0x2a, 0x6b, 0xc2, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x4c, 0x1c, 0x0d, 0x02, 0x2c, 0xc7, 0xe4, 0x92, 0x85, 0x80,
    0xfe, 0x62, 0x75, 0xcb, 0x86, 0x37, 0x86, 0x04, 0xb6, 0x86, 0xce, 0x75,
    0x04, 0x40, 0xfe, 0x43, 0x7f, 0xce, 0x8f, 0xae, 0xa7, 0x2f, 0xc1, 0xfe,
    0x62, 0xae, 0x2f, 0x46, 0xf7, 0x37, 0x61, 0xfe, 0xa2, 0xce, 0x0e, 0xf7,
    0x4f, 0x2f, 0xce, 0x03, 0x2c, 0xc8, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8,
    0x0b, 0xa8, 0x0b, 0xf4, 0xd9, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x23, 0xc7, 0x75,
    0x8c, 0x1c, 0x04, 0x04, 0x04, 0x97, 0x2f, 0xae, 0x37, 0x86, 0x4f, 0xce,
    0x75, 0x03, 0x2c, 0xc9, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8,
    0x0b, 0xf4, 0xd9, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c,
    0x04, 0x04, 0x04, 0x97, 0x2f, 0xae, 0x37, 0x86, 0x4f, 0xce, 0x75};

const uint8_t PES_8773087[] = {
    0x10, 0x03, 0x2c, 0xe7, 0xe4, 0xa8, 0x6d, 0xa8, 0x2e, 0xfe, 0xff, 0x2e,
    0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e,
    0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e,
    0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0xdc, 0x08, 0x00, 0x03,
    0x2c, 0xe8, 0xe4, 0x0b, 0x6d, 0xa8, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a,
    0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a,
    0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a,
    0x57, 0x57, 0x57, 0xf4, 0x57, 0x7a, 0xa8, 0x25, 0xee, 0x03, 0x2c, 0xe9,
    0xe4, 0xa8, 0x31, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xb0, 0xd0, 0xd0, 0xb5, 0xcb,
    0xba, 0xfd, 0x51, 0x51, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x2c, 0xea, 0xe4, 0xa8,
    0xd9, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0xb0, 0xd0, 0xd0, 0xb5, 0xcb, 0xba, 0x75,
    0x51, 0x51, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x2c, 0xc7, 0xe4, 0x92, 0xa8, 0x40,
    0x1c, 0x40, 0x0b, 0xa8, 0xa8, 0x92, 0xd9, 0x2a, 0x6b, 0xcd, 0x2a, 0xa2,
    0x1a, 0x2a, 0xc1, 0x2a, 0x6b, 0xcd, 0xe0, 0x4c, 0x6d, 0x8c, 0x04, 0x23,
    0xc7, 0x75, 0x8c, 0x1c, 0xc1, 0x04, 0x04, 0x2f, 0xae, 0x37, 0x86, 0x4f,
    0xce, 0x75, 0x75, 0x02, 0x2c, 0xc8, 0xe4, 0x92, 0xa8, 0x40, 0x1c, 0x40,
    0x0b, 0xa8, 0xa8, 0x92, 0xd9, 0x2a, 0x6b, 0xcd, 0x2a, 0xa2, 0x1a, 0x2a,
    0xc1, 0x2a, 0x6b, 0xcd, 0xe0, 0x4c, 0x6d, 0x8c, 0x04, 0x23, 0xc7, 0x75,
    0x8c, 0x1c, 0xc1, 0x04, 0x04, 0x2f, 0xae, 0x37, 0x86, 0x4f, 0xce, 0x75,
    0x75, 0x02, 0x2c, 0xc9, 0xe4, 0x92, 0xa8, 0x40, 0x1c, 0x40, 0x0b, 0xa8,
    0xa8, 0x92, 0xd9, 0x2a, 0x6b, 0xcd, 0x2a, 0xa2, 0x1a, 0x2a, 0xc1, 0x2a,
    0x6b, 0xcd, 0xe0, 0x4c, 0x6d, 0x8c, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c,
    0xc1, 0x04, 0x04, 0x2f, 0xae, 0x37, 0x86, 0x4f, 0xce, 0x75, 0x75};

const uint8_t PES_8937764[] = {
    0x10, 0x02, 0x2c, 0xe7, 0xe4, 0x31, 0xe3, 0x04, 0x61, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x86, 0xc7, 0x86, 0xce, 0x86,
    0xce, 0x15, 0x86, 0x94, 0x2f, 0x6e, 0xcd, 0x75, 0xc7, 0x86, 0x2f, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x02,
    0x2c, 0xe8, 0xe4, 0x92, 0x31, 0x04, 0x80, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x15, 0x86,
    0x94, 0xbc, 0x86, 0x4f, 0x4f, 0xf7, 0x6e, 0x86, 0x04, 0x02, 0x2c, 0xe9,
    0xe4, 0x31, 0x31, 0x80, 0xb9, 0x01, 0xb0, 0xa2, 0x37, 0x04, 0x2f, 0xa7,
    0xb6, 0x0e, 0xce, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x75, 0x75, 0x8c, 0x6d, 0x0d, 0x02, 0x2c, 0xea, 0xe4, 0x31,
    0xd9, 0xe0, 0xb9, 0x01, 0x04, 0x05, 0x76, 0x26, 0xa7, 0x1f, 0x04, 0x4f,
    0x7f, 0x0e, 0x97, 0x26, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
    0x75, 0x75, 0x4c, 0x1c, 0x4c, 0x02, 0x2c, 0xc7, 0xe4, 0x92, 0x85, 0x80,
    0xfe, 0x05, 0x76, 0x26, 0xa7, 0x1f, 0x40, 0xfe, 0x0b, 0x4f, 0xf7, 0xe6,
    0x4f, 0x86, 0xb6, 0x86, 0xc7, 0x97, 0x7a, 0xc1, 0xfe, 0xa2, 0xce, 0x0e,
    0xf7, 0x4f, 0x2f, 0xce, 0x61, 0xfe, 0x32, 0xf7, 0x2f, 0xa7, 0x4f, 0x97,
    0xa7, 0xce, 0x04, 0x03, 0x2c, 0xc8, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8,
    0x0b, 0xa8, 0x0b, 0xf4, 0xd9, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x23, 0xc7, 0x75,
    0x8c, 0x1c, 0x04, 0x04, 0x04, 0x86, 0x4f, 0xce, 0x75, 0x75, 0x75, 0x8c,
    0x8c, 0x03, 0x2c, 0xc9, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8,
    0x0b, 0xf4, 0xd9, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x23, 0xc7, 0x75, 0x8c, 0x1c,
    0x04, 0x04, 0x04, 0x86, 0x4f, 0xce, 0x75, 0x75, 0x75, 0x8c, 0x8c};

// Start (packet0, page88) with packet26 and row 18 left (packet18)
const uint8_t PES_867681[] = {
    0x10, 0x03, 0x2c, 0xf6, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8,
    0x0b, 0xf4, 0xa8, 0xb3, 0x83, 0x32, 0xa2, 0x73, 0x2a, 0xa2, 0x73, 0x23,
    0x83, 0x73, 0x2a, 0xcb, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
    0x2c, 0xd4, 0xe4, 0xa8, 0x6d, 0xa8, 0x9e, 0xc9, 0x00, 0x4e, 0x93, 0xa7,
    0x90, 0x53, 0xa7, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x03, 0x2c, 0xd6,
    0xe4, 0xa8, 0xe3, 0xb0, 0x04, 0x04, 0x04, 0x04, 0xd0, 0xd0, 0xb5, 0x32,
    0xae, 0xd6, 0xa7, 0x04, 0x85, 0x51, 0x51, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04};

// row 22 right (packet22)
const uint8_t PES_871281[] = {
    0x10, 0x03, 0x2c, 0xf4, 0xe4, 0xa8, 0xd9, 0xb0, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0xd0, 0xd0, 0xb5, 0x52, 0xa7, 0x04, 0x6e, 0x86, 0x97, 0xce,
    0x04, 0x86, 0xae, 0x1f, 0x04, 0xc7, 0xf7, 0xae, 0x4f, 0xce, 0x04, 0x26,
    0xe5, 0xa7, 0x2f, 0xa7, 0x75, 0x51, 0x51, 0x04, 0x04, 0x04, 0x04};

// End (packet 0, page 88)
const uint8_t PES_1011695[] = {
    0x10, 0x03, 0x2c, 0xf6, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8,
    0x0b, 0xf4, 0xa8, 0xb3, 0x83, 0x32, 0xa2, 0x73, 0x2a, 0xa2, 0x73, 0x23,
    0x83, 0x73, 0x2a, 0xcb, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04};

// Start (packet0, page 88) with packet26 and row 20 (centered yellow)
// (packet20)
const uint8_t PES_1033297[] = {
    0x10, 0x03, 0x2c, 0xf6, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8,
    0x0b, 0xf4, 0xa8, 0xb3, 0x83, 0x32, 0xa2, 0x73, 0x2a, 0xa2, 0x73, 0x23,
    0x83, 0x73, 0x2a, 0xcb, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
    0x2c, 0xd4, 0xe4, 0xa8, 0x6d, 0xa8, 0x06, 0xc9, 0x01, 0x62, 0x93, 0xa6,
    0x9e, 0xc9, 0x00, 0xf4, 0xa2, 0x86, 0x06, 0xa3, 0xa7, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff,
    0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x2e, 0xfe, 0xff, 0x03, 0x2c, 0xd6,
    0xe4, 0xa8, 0x31, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0xb0, 0xc1, 0xd0, 0xd0, 0x52, 0xe5, 0x86, 0x97, 0x04,
    0x37, 0xf7, 0xae, 0x0e, 0xa7, 0x51, 0x51, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04};

// row 22 centered blue on yellow background (packet22)
const uint8_t PES_1036900[] = {
    0x10, 0x03, 0x2c, 0xf4, 0xe4, 0xa8, 0xd9, 0x04, 0x04, 0xb0, 0xc1, 0xb9,
    0x20, 0xd0, 0xd0, 0x37, 0xe5, 0x97, 0x76, 0x97, 0x2f, 0x97, 0x86, 0x2f,
    0x97, 0xf7, 0x76, 0x04, 0x86, 0x04, 0x37, 0xe5, 0x86, 0x37, 0xe6, 0xa7,
    0x46, 0x4f, 0xa7, 0x75, 0x51, 0x51, 0x04, 0x04, 0x04, 0x04, 0x04};

// End (packet 0, page 88)
const uint8_t PES_1173713[] = {
    0x10, 0x03, 0x2c, 0xf6, 0xe4, 0xa8, 0xa8, 0x0b, 0x0b, 0xa8, 0x0b, 0xa8,
    0x0b, 0xf4, 0xa8, 0xb3, 0x83, 0x32, 0xa2, 0x73, 0x2a, 0xa2, 0x73, 0x23,
    0x83, 0x73, 0x2a, 0xcb, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04};

const uint32_t kPesPid = 123;

}  // namespace

class EsParserTeletextTest : public ::testing::Test {
 public:
  void OnNewStreamInfo(uint32_t pes_pid,
                       std::shared_ptr<StreamInfo> stream_info) {
    stream_info_ = stream_info;
  }
  void OnEmitTextSample(uint32_t pes_pid,
                        std::shared_ptr<TextSample> text_sample) {
    text_sample_ = text_sample;
    text_samples_.push_back(text_sample);
  }

 protected:
  std::shared_ptr<StreamInfo> stream_info_;
  std::vector<std::shared_ptr<TextSample>> text_samples_;
  std::shared_ptr<TextSample> text_sample_;
};

TEST_F(EsParserTeletextTest, descriptor_substreams_has_index_888_language_cat) {
  auto on_new_stream = std::bind(&EsParserTeletextTest::OnNewStreamInfo, this,
                                 kPesPid, std::placeholders::_1);
  auto on_emit_text = std::bind(&EsParserTeletextTest::OnEmitTextSample, this,
                                kPesPid, std::placeholders::_1);

  std::unique_ptr<EsParserTeletext> es_parser_teletext(new EsParserTeletext(
      kPesPid, on_new_stream, on_emit_text, DESCRIPTOR, 12));

  const auto parse_result =
      es_parser_teletext->Parse(PES_283413, sizeof(PES_283413), 283413, 0);
  EXPECT_TRUE(parse_result);

  EXPECT_NE(nullptr, stream_info_.get());
  auto text_stream_info = static_cast<TextStreamInfo*>(stream_info_.get());
  auto& sub_streams = text_stream_info->sub_streams();

  EXPECT_EQ(2, sub_streams.size());
  auto sub_streams_itr = sub_streams.find(888);
  EXPECT_NE(sub_streams.end(), sub_streams_itr);
  EXPECT_EQ("cat", sub_streams_itr->second.language);
}

TEST_F(EsParserTeletextTest, pes_283413_line_emitted_on_next_pes) {
  auto on_new_stream = std::bind(&EsParserTeletextTest::OnNewStreamInfo, this,
                                 kPesPid, std::placeholders::_1);
  auto on_emit_text = std::bind(&EsParserTeletextTest::OnEmitTextSample, this,
                                kPesPid, std::placeholders::_1);

  std::unique_ptr<EsParserTeletext> es_parser_teletext(new EsParserTeletext(
      kPesPid, on_new_stream, on_emit_text, DESCRIPTOR, 12));

  auto parse_result =
      es_parser_teletext->Parse(PES_283413, sizeof(PES_283413), 283413, 0);
  EXPECT_TRUE(parse_result);

  parse_result =
      es_parser_teletext->Parse(PES_407876, sizeof(PES_407876), 407876, 0);
  EXPECT_TRUE(parse_result);

  EXPECT_NE(nullptr, text_sample_.get());
  EXPECT_EQ(283413, text_sample_->start_time());
  EXPECT_EQ(407876, text_sample_->EndTime());
  EXPECT_EQ("Bon dia!", text_sample_->body().body);
  EXPECT_EQ("black", text_sample_->body().style.backgroundColor);
  EXPECT_EQ("white", text_sample_->body().style.color);
  TextSettings settings = text_sample_->settings();
  EXPECT_EQ(TextAlignment::kCenter, settings.text_alignment);
  EXPECT_TRUE(settings.line.has_value());
  EXPECT_EQ(11, settings.line.value().value);
  EXPECT_EQ(TextUnitType::kLines, settings.line.value().type);
}

TEST_F(EsParserTeletextTest, multiple_lines_with_same_pts) {
  auto on_new_stream = std::bind(&EsParserTeletextTest::OnNewStreamInfo, this,
                                 kPesPid, std::placeholders::_1);
  auto on_emit_text = std::bind(&EsParserTeletextTest::OnEmitTextSample, this,
                                kPesPid, std::placeholders::_1);

  std::unique_ptr<EsParserTeletext> es_parser_teletext(new EsParserTeletext(
      kPesPid, on_new_stream, on_emit_text, DESCRIPTOR, 12));

  auto parse_result =
      es_parser_teletext->Parse(PES_8768632, sizeof(PES_8768632), 8768632, 0);
  EXPECT_TRUE(parse_result);

  parse_result =
      es_parser_teletext->Parse(PES_8773087, sizeof(PES_8773087), 8773087, 0);
  EXPECT_TRUE(parse_result);

  parse_result =
      es_parser_teletext->Parse(PES_8937764, sizeof(PES_8937764), 8937764, 0);
  EXPECT_TRUE(parse_result);

  EXPECT_NE(nullptr, text_sample_.get());
  EXPECT_EQ(8768632, text_sample_->start_time());
  EXPECT_EQ(8937764, text_sample_->EndTime());
  EXPECT_EQ(3, text_sample_->body().sub_fragments.size());
  EXPECT_EQ("-Sí?", text_sample_->body().sub_fragments[0].body);
  EXPECT_TRUE(text_sample_->body().sub_fragments[1].newline);
  EXPECT_EQ("-Sí.", text_sample_->body().sub_fragments[2].body);
  TextSettings settings = text_sample_->settings();
  EXPECT_EQ(10, settings.line.value().value);
  EXPECT_EQ("ttx_10", settings.region);
  EXPECT_EQ(1, text_samples_.size());
}

// separate_lines_with_slightly_different_pts has the original lines
// 18 and 22, with different alignment, which means that they should
// result in two parallel text samples.
TEST_F(EsParserTeletextTest, separate_lines_with_slightly_different_pts) {
  auto on_new_stream = std::bind(&EsParserTeletextTest::OnNewStreamInfo, this,
                                 kPesPid, std::placeholders::_1);
  auto on_emit_text = std::bind(&EsParserTeletextTest::OnEmitTextSample, this,
                                kPesPid, std::placeholders::_1);

  std::unique_ptr<EsParserTeletext> es_parser_teletext(new EsParserTeletext(
      kPesPid, on_new_stream, on_emit_text, DESCRIPTOR, 12));

  auto parse_result =
      es_parser_teletext->Parse(PES_867681, sizeof(PES_867681), 867681, 0);
  EXPECT_TRUE(parse_result);

  parse_result =
      es_parser_teletext->Parse(PES_871281, sizeof(PES_871281), 871281, 0);
  EXPECT_TRUE(parse_result);

  parse_result =
      es_parser_teletext->Parse(PES_1011695, sizeof(PES_1011695), 1011695, 0);
  EXPECT_TRUE(parse_result);

  EXPECT_NE(nullptr, text_sample_.get());
  EXPECT_EQ(2, text_samples_.size());
  // The subtitles should get the same start and end time
  EXPECT_EQ(867681, text_samples_[0]->start_time());
  EXPECT_EQ(867681, text_samples_[1]->start_time());
  EXPECT_EQ(1011695, text_samples_[0]->EndTime());
  EXPECT_EQ(1011695, text_samples_[0]->EndTime());
  EXPECT_EQ(1, text_samples_[0]->body().sub_fragments.size());
  EXPECT_EQ(1, text_samples_[1]->body().sub_fragments.size());
  EXPECT_EQ("-Luke !", text_samples_[0]->body().sub_fragments[0].body);
  EXPECT_EQ("ttx_9", text_samples_[0]->settings().region);
  EXPECT_EQ(TextAlignment::kLeft, text_samples_[0]->settings().text_alignment);
  EXPECT_EQ("-Je vais aux cours d'été.",
            text_samples_[1]->body().sub_fragments[0].body);
  EXPECT_EQ(11, text_samples_[1]->settings().line.value().value);
  EXPECT_EQ("ttx_11", text_samples_[1]->settings().region);
  EXPECT_EQ(TextAlignment::kCenter,
            text_samples_[1]->settings().text_alignment);
}

// consecutive_lines_with_slightly_different_pts has the original lines
// 20 and 22 with same alignment, which means that they should
// result in one text sample with two lines.
TEST_F(EsParserTeletextTest, consecutive_lines_with_slightly_different_pts) {
  auto on_new_stream = std::bind(&EsParserTeletextTest::OnNewStreamInfo, this,
                                 kPesPid, std::placeholders::_1);
  auto on_emit_text = std::bind(&EsParserTeletextTest::OnEmitTextSample, this,
                                kPesPid, std::placeholders::_1);

  std::unique_ptr<EsParserTeletext> es_parser_teletext(new EsParserTeletext(
      kPesPid, on_new_stream, on_emit_text, DESCRIPTOR, 12));

  auto parse_result =
      es_parser_teletext->Parse(PES_1033297, sizeof(PES_1033297), 1033297, 0);
  EXPECT_TRUE(parse_result);

  parse_result =
      es_parser_teletext->Parse(PES_1036900, sizeof(PES_1036900), 1036900, 0);
  EXPECT_TRUE(parse_result);

  parse_result =
      es_parser_teletext->Parse(PES_1173713, sizeof(PES_1173713), 1173713, 0);
  EXPECT_TRUE(parse_result);

  EXPECT_NE(nullptr, text_sample_.get());
  EXPECT_EQ(1, text_samples_.size());
  // The subtitles should get the same start and end time
  EXPECT_EQ(1033297, text_sample_->start_time());
  EXPECT_EQ(1173713, text_sample_->EndTime());
  EXPECT_EQ(3, text_sample_->body().sub_fragments.size());
  TextSettings settings = text_sample_->settings();
  EXPECT_EQ(10, settings.line.value().value);
  EXPECT_EQ("ttx_10", settings.region);
  EXPECT_EQ(TextAlignment::kCenter, settings.text_alignment);
  EXPECT_EQ("J'ai loupé", text_sample_->body().sub_fragments[0].body);
  EXPECT_EQ("yellow", text_sample_->body().sub_fragments[0].style.color);
  EXPECT_TRUE(text_sample_->body().sub_fragments[1].newline);
  EXPECT_EQ("l'initiation à l'algèbre.",
            text_sample_->body().sub_fragments[2].body);
  EXPECT_EQ("yellow",
            text_sample_->body().sub_fragments[2].style.backgroundColor);
  EXPECT_EQ("blue", text_sample_->body().sub_fragments[2].style.color);
}

}  // namespace mp2t
}  // namespace media
}  // namespace shaka
